package com.yycx.module.system.provider.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.xiaoymin.knife4j.spring.extension.ApiAuthorExtension;
import com.yycx.common.constants.QueueConstants;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaDelete;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.security.OpenHelper;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.module.system.client.entity.SysArea;
import com.yycx.module.system.client.entity.SysCollecon;
import com.yycx.common.enums.ColleconEnum;
import com.yycx.module.system.provider.mapper.SysColleconMapper;
import com.yycx.module.system.provider.service.SysAreaService;
import com.yycx.module.system.provider.service.SysColleconService;
import com.yycx.module.system.provider.service.SysGroupColleconService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 收藏点赞关注表 服务实现类
 *
 * @author flyme
 * @date 2019-06-13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysColleconServiceImpl extends BaseServiceImpl<SysColleconMapper, SysCollecon> implements SysColleconService {

    @Autowired
    private SysGroupColleconService groupColleconService;


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public SysCollecon findCollecon(Long targetId, Long userId, ColleconEnum colleconEnum, String entityName) {
        CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
        cq.eq("targetId", targetId);
        cq.eq("optType", colleconEnum.getCode());
        cq.eq("targetEntity", entityName);
        cq.eq(true, "userId", userId);
        return getOne(cq);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody collecon(Long targetId, Long targetUserId, ColleconEnum colleconEnum, String entityName, Long[] groupIds) {
        Long userId = commonBeanUtils.getUserId();
        SysCollecon sysCollecon = findCollecon(targetId, userId, colleconEnum, entityName);
        if (ObjectUtils.isEmpty(sysCollecon)) {
            sysCollecon = new SysCollecon();
            sysCollecon.setOptType(colleconEnum.getCode());
            sysCollecon.setTargetId(targetId);
            sysCollecon.setTargetUserId(targetUserId);
            sysCollecon.setUserId(userId);
            sysCollecon.setTargetEntity(entityName);
            save(sysCollecon);
            if (FlymeUtils.isNotEmpty(groupIds)) {
                setGroup(new Long[]{sysCollecon.getColleconId()}, groupIds);
            }
            //发布事件
            sysCollecon.setIsCancel(false);
            rabbitMqClient.publishEvent(sysCollecon);
            return ResultBody.ok(colleconEnum.getName() + "成功", true);
        } else {
            removeById(sysCollecon.getColleconId());
            //发布事件
            sysCollecon.setIsCancel(true);
            rabbitMqClient.publishEvent(sysCollecon);
            groupColleconService.deleteByColleconIds(new Long[]{sysCollecon.getColleconId()});
            return ResultBody.ok("已取消" + colleconEnum.getName(), false);
        }

    }

    @Override
    public Boolean setGroup(Long[] colleconIds, Long[] groupIds) {
        //先清空分组
        groupColleconService.deleteByColleconIds(colleconIds);
        //重新设置分组
        return groupColleconService.setColleconGroup(colleconIds, groupIds);
    }

    @Override
    public Boolean deleteByTargetEntity(String targetEntity) {
        ApiAssert.isNotEmpty("类型不能为空", targetEntity);
        Long userId = commonBeanUtils.getUserId();
        CriteriaDelete cd = new CriteriaDelete();
        cd.eq(true, "userId", userId);
        cd.eq(true, "targetEntity", targetEntity);
        return remove(cd);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public long countCollecon(Long targetId, ColleconEnum colleconEnum, Class cls) {
        Long userId = commonBeanUtils.getUserId();
        if (FlymeUtils.allNotNull(userId, targetId)) {
            CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
            cq.eq(true, "targetId", targetId);
            cq.eq("optType", colleconEnum.getCode());
            cq.eq("targetEntity", cls.getSimpleName());
            cq.eq(true, "userId", userId);
            return count(cq);
        } else {
            return 0L;
        }
    }

    @Override
    public long countAllCollecon(Long targetId, ColleconEnum colleconEnum, Class cls) {
        if (FlymeUtils.isNotEmpty(targetId)) {
            CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
            cq.eq("targetId", targetId);
            cq.eq("optType", colleconEnum.getCode());
            cq.eq("targetEntity", cls.getSimpleName());
            return count(cq);
        } else {
            return 0;
        }

    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<EntityMap> selectColleconProductByCompanyId(Long companyId, int limit) {
        EntityMap map = new EntityMap();
        map.put("companyId", companyId);
        map.put("limit", limit);
        return baseMapper.selectColleconProductByCompanyId(map);
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<SysCollecon> cq, SysCollecon collecon, EntityMap requestMap) {
        //是否是私有数据
        Integer isPrivate = requestMap.get("isPrivate", 0);
        cq.select("collecon.colleconId", "collecon.targetId", "collecon.targetEntity", "collecon.userId");
        if (isPrivate.equals(0)) {
            Long userId = OpenHelper.getUserId();
            cq.eq("collecon.userId", userId);
        }
        return ResultBody.ok();
    }


    @Override
    public ResultBody afterDelete(CriteriaDelete cd, Serializable[] ids) {
        groupColleconService.deleteByColleconIds(ids);
        return super.afterDelete(cd, ids);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public long countCountByTargetCompany(Long targetCompanyId, ColleconEnum colleconEnum, Class cls) {
        CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
        cq.eq(true, "targetCompanyId", targetCompanyId);
        cq.eq("optType", colleconEnum.getCode());
        cq.eq("targetEntity", cls.getSimpleName());
        return count(cq);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public long countCountByUser(Long userId, ColleconEnum colleconEnum, Class cls) {
        CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
        cq.eq("optType", colleconEnum.getCode());
        cq.eq("targetEntity", cls.getSimpleName());
        cq.eq(true, "userId", userId);
        return count(cq);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public EntityMap totalByTargetEntity() {
        EntityMap result = new EntityMap();
        CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
        String begin = DateUtils.minusDays(30).toString();
        Long companyId = OpenHelper.getCompanyId();
        cq.select("count(colleconId) resultCount");
        cq.eq("optType", 1);
        cq.eq("targetEntity", "ProdShop");
        cq.eq("targetId", companyId);
        EntityMap totalMap = findOne(cq);
        cq.select("DATE_FORMAT(createTime,'%Y-%m-%d') dayTime");
        cq.ge("createTime", begin);
        cq.groupBy("dayTime");
        cq.orderByAsc("dayTime");
        List<EntityMap> dataList = selectEntityMap(cq);
        List<EntityMap> resultList = new ArrayList<>();
        Integer monthCount = 0;
        for (int i = 1; i <= 30; i++) {
            EntityMap map = new EntityMap();
            String date = DateUtils.plusDays(DateUtils.minusDays(30), i);
            map.put("x", date);
            map.put("y", 0);
            for (EntityMap entityMap : dataList) {
                String dayTime = entityMap.get("dayTime");
                Integer resultCount = entityMap.getInt("resultCount", 0);
                monthCount += resultCount;
                if (date.equals(dayTime)) {
                    map.put("y", resultCount);
                }
            }
            resultList.add(map);
        }
        Integer totalCount = totalMap.getInt("resultCount", 0);
        result.put("list", resultList);
        result.put("totalCount", totalCount);
        result.put("monthCount", monthCount);
        return result;
    }

    @Override
    public long countCountByTargetUser(Long targetUserId, ColleconEnum colleconEnum, String targetEntity) {
        CriteriaQuery cq = new CriteriaQuery(SysCollecon.class);
        cq.eq("optType", colleconEnum.getCode());
        cq.eq("targetEntity", targetEntity);
        cq.eq(true, "targetUserId", targetUserId);
        return count(cq);
    }
}
